/*
*  MovementEngine.c
*  DamasIA
*
*  Created by Anderson on 09/06/12.
*  Copyright 2012 __MyCompanyName__. All rights reserved.
*
*/


#include "MovementEngine.h"
//#include "BoardManagement.h"


//***************************	ESSAS DUAS FUNCOES SOH ESTAO TESTANDO SE A PEÇA NAO ESTA 		***************************
//***************************	INDO PARA FORA DO TABULEIRO										***************************

BOOLEAN validaCoordenada(int x, int y)
{
	if ((x < 0) || (x > 7)){
		//		printf("Coordenada X da origem invalida!\n");
		return FALSE;
	}
	else if ((y < 0) || (y > 7)){
		//		printf("Coordenada Y da origem invalida!\n");
		return FALSE;
	}
	else
	{
		return TRUE;
	}	
}

BOOLEAN validOrig(Board b, int xo, int yo, char peca){
	//se a coordenada for fora dos limites do tabuleiro
	if (!(validaCoordenada(xo, yo)))
	{
		return FALSE;
	}
	//se passar como origem um lugar sem peca
	else if (b.pieces[xo][yo]== ' ')
	{
		return FALSE;     
	}
	//se passar como origem um lugar com peca do oponente
	else if (toupper(b.pieces[xo][yo])!=toupper(peca))
	{
		return FALSE;     
	}
	else if((peca == 'o')||(peca == 'O'))
	{
		//se a peca branca esta na coluna A
		if(yo==0)
		{
			//se pode mover a peca para a direita
			if (pecaBrancaPodeMoverParaDireita(b, xo, yo))
			{
				return TRUE;
			}
			else
			{
				return FALSE;
			}
		}
		//se a peca branca esta na coluna H
		else if(yo ==7)
		{
			//se pode mover a peca para a esquerda
			if (pecaBrancaPodeMoverParaEsquerda(b, xo, yo))
			{
				return TRUE;
			}
			else
			{
				return FALSE;
			}              
		}
		//se nao pode mover a peca nem para direita nem para esquerda
		else if ((!(pecaBrancaPodeMoverParaDireita(b, xo, yo)))&&(!(pecaBrancaPodeMoverParaEsquerda(b, xo, yo))))
		{
			return FALSE;
		}
	}
	else if((peca == 'x')||(peca == 'X'))
	{
		//se a peca branca esta na coluna A
		if(yo==0)
		{
			//se pode mover a peca para a esquerda
			if (pecaPretaPodeMoverParaEsquerda(b, xo, yo))
			{
				return TRUE;
			}
			else
			{
				return FALSE;
			}
		}
		//se a peca branca esta na coluna H
		else if(yo ==7)
		{
			//se pode mover a peca para a direita
			if (pecaPretaPodeMoverParaDireita(b, xo, yo))
			{
				return TRUE;
			}
			else
			{
				return FALSE;
			}              
		}
		//se nao pode mover a peca nem para direita nem para esquerda
		else if ((!(pecaPretaPodeMoverParaDireita(b, xo, yo)))&&(!(pecaPretaPodeMoverParaEsquerda(b, xo, yo))))
		{
			return FALSE;
		}
	}
	
	return TRUE;
}

BOOLEAN validDest(Board b, int xd, int yd, int xo, int yo, char peca){
	//se a coordenada for fora dos limites do tabuleiro
	if (!(validaCoordenada(xd, yd)))
	{
		return FALSE;
	}
	//se a peca branca tentar andar para tras
	else if	((xd<xo) && (peca=='o')){
		return FALSE; 
	}
	//se a peca preta tentar andar para tras
	else if	((xd>xo) && (peca=='x')){
		return FALSE; 
	}    
	//se ja houver uma peca no lugar do destino
	else if (b.pieces[xd][yd]!=' ')
	{
		return FALSE;     
	}
	//se tentar andar para o lado
	else if	(xd==xo){
		return FALSE; 
	}
	//se tentar andar para a frente
	else if (yo==yd)
	{
		return FALSE;         
	}
	//se eh movimento para comer uma peca preta(x) na diagonal direita
	else if (movParaComerPecaPretaADireita(b, xo, yo, xd,yd))//((xd-xo==2)&&(yd==yo+2)&&(b.pieces[xo+1][yo+1]=='x')&&(peca=='o'))
	{
		return TRUE;         
	}
	//se eh movimento para comer uma peca preta(x) na diagonal esquerda
	else if (movParaComerPecaPretaAEsquerda(b, xo, yo, xd, yd))//((xd-xo==2)&&(yd==yo-2)&&(b.pieces[xo+1][yo-1]=='x')&&(peca=='o'))
	{
		return TRUE;         
	}
	//se eh movimento para proxima casa na diagonal seja a direita ou esquerda
	else if ((xd-xo==1)&&((yd==yo+1)||(yd==yo-1))&&(b.pieces[xd][yd]==' ')&&(peca=='o'))
	{
		return TRUE;
	}
	//se eh movimento para comer uma peca branca(o) na diagonal direita
	else if (movParaComerPecaBrancaADireita(b, xo, yo, xd, yd))//((xd-xo==-2)&&(yd==yo+2)&&(b.pieces[xo-1][yo+1]=='o')&&(peca=='x'))
	{
		return TRUE;         
	}
	//se eh movimento para comer uma peca branca(o) na diagonal esquerda
	else if (movParaComerPecaBrancaAEsquerda(b, xo, yo, xd, yd))//((xd-xo==-2)&&(yd==yo-2)&&(b.pieces[xo-1][yo-1]=='o')&&(peca=='x'))
	{
		return TRUE;         
	}
	//se eh movimento para proxima casa na diagonal seja a direita ou esquerda
	else if ((xd-xo==-1)&&((yd==yo+1)||(yd==yo-1))&&(b.pieces[xd][yd]==' ')&&(peca=='x'))
	{
		return TRUE;
	}

	return FALSE;
}

BOOLEAN movParaComerPecaPretaADireita(Board b, int xo, int yo, int xd, int yd)
{
	if ((xd-xo==2)&&(yd==yo+2)&&(b.pieces[xo+1][yo+1]=='x'))
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

BOOLEAN movParaComerPecaPretaAEsquerda(Board b, int xo, int yo, int xd, int yd)
{
	if ((xd-xo==2)&&(yd==yo-2)&&(b.pieces[xo+1][yo-1]=='x'))                
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}        
}

BOOLEAN movParaComerPecaBrancaADireita(Board b, int xo, int yo, int xd, int yd)
{
	if ((xd-xo==-2)&&(yd==yo+2)&&(b.pieces[xo-1][yo+1]=='o'))        
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}        
}

BOOLEAN movParaComerPecaBrancaAEsquerda(Board b, int xo, int yo, int xd, int yd)
{
	if ((xd-xo==-2)&&(yd==yo-2)&&(b.pieces[xo-1][yo-1]=='o'))
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}        
}

BOOLEAN podeComerPecaPretaADireita(Board b, int xo, int yo)
{
	if ((validaCoordenada(xo+2, yo+2))&&(validaCoordenada(xo+1, yo+1)))
	{
		if ((b.pieces[xo+2][yo+2]==' ')&&(b.pieces[xo+1][yo+1]=='x'))    
		{
			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}  
	else
	{
		return FALSE;
	}   
}

BOOLEAN podeComerPecaPretaAEsquerda(Board b, int xo, int yo)
{
	if ((validaCoordenada(xo+2, yo-2))&&(validaCoordenada(xo+1, yo-1)))
	{
		if ((b.pieces[xo+2][yo-2]==' ')&&(b.pieces[xo+1][yo-1]=='x'))    
		{
			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}  
	else
	{
		return FALSE;
	}       
}

BOOLEAN podeComerPecaBrancaADireita(Board b, int xo, int yo)
{
	if ((validaCoordenada(xo-2, yo-2))&&(validaCoordenada(xo-1, yo-1)))
	{
		if ((b.pieces[xo-2][yo-2]==' ')&&(b.pieces[xo-1][yo-1]=='o'))    
		{
			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}  
	else
	{
		return FALSE;
	}       
}

BOOLEAN podeComerPecaBrancaAEsquerda(Board b, int xo, int yo)
{
	if ((validaCoordenada(xo-2, yo+2))&&(validaCoordenada(xo-1, yo+1)))
	{
		if ((b.pieces[xo-2][yo+2]==' ')&&(b.pieces[xo-1][yo+1]=='o'))    
		{
			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}  
	else
	{
		return FALSE;
	}   
}

BOOLEAN pecaBrancaPodeMoverParaDireita(Board b, int xo, int yo)
{
	//verifica se a peca branca que se deseja movimentar nao esta travada
	if((b.pieces[xo+1][yo+1]=='o')||(b.pieces[xo+1][yo+1]=='O'))
	{
		return FALSE;                  
	}
	//se a proxima peca a direita eh do oponente
	else if ((b.pieces[xo+1][yo+1]=='x')||(b.pieces[xo+1][yo+1]=='X'))
	{
		//se ainda tem tabuleiro depois da peca do oponente
		if (validaCoordenada(xo+2, yo+2))
		{
			//se o lugar apos a peca do oponente esta vago
			if (b.pieces[xo+2][yo+2]!=' ')
			{
				return FALSE;
			}
			else
			{
				return TRUE;
			}
		}
		else
		{
			return FALSE;
		}
	}
	return TRUE;	
}

BOOLEAN pecaBrancaPodeMoverParaEsquerda(Board b, int xo, int yo)
{
	//verifica se a peca branca que se deseja movimentar nao esta travada
	if((b.pieces[xo+1][yo-1]=='o')||(b.pieces[xo+1][yo-1]=='O'))
	{
		return FALSE;                           
	}
	//se a proxima peca a esquerda eh do oponente
	else if ((b.pieces[xo+1][yo-1]=='x')||(b.pieces[xo+1][yo-1]=='X'))
	{
		//se ainda tem tabuleiro depois da peca do oponente
		if (validaCoordenada(xo+2, yo-2))
		{
			//se o lugar apos a peca do oponente esta vago
			if (b.pieces[xo+2][yo-2]!=' ')
			{
				return FALSE;
			}
			else
			{
				return TRUE;
			}
		}
		else
		{
			return FALSE;
		}       
	}        
	return TRUE;	
}

BOOLEAN pecaPretaPodeMoverParaEsquerda(Board b, int xo, int yo)
{
	//verifica se a peca branca que se deseja movimentar nao esta travada
	if((b.pieces[xo-1][yo+1]=='x')||(b.pieces[xo-1][yo+1]=='X'))
	{
		return FALSE;                  
	}
	//se a proxima peca a esquerda eh do oponente	
	else if ((b.pieces[xo-1][yo+1]=='o')||(b.pieces[xo-1][yo+1]=='O'))
	{
		//se ainda tem tabuleiro depois da peca do oponente
		if (validaCoordenada(xo-2, yo+2))
		{
			//se o lugar apos a peca do oponente esta vago
			if (b.pieces[xo-2][yo+2]!=' ')
			{
				return FALSE;
			}
			else
			{
				return TRUE;
			}
		}
		else
		{
			return FALSE;
		}
	}
	
	return TRUE;
}

BOOLEAN pecaPretaPodeMoverParaDireita(Board b, int xo, int yo)
{
	//verifica se a peca branca que se deseja movimentar nao esta travada
	if((b.pieces[xo-1][yo-1]=='x')||(b.pieces[xo-1][yo-1]=='X'))
	{
		return FALSE;                           
	}
	//se a proxima peca a direita eh do oponente
	else if ((b.pieces[xo-1][yo-1]=='o')||(b.pieces[xo-1][yo-1]=='O'))
	{
		//se ainda tem tabuleiro depois da peca do oponente
		if (validaCoordenada(xo-2, yo-2))
		{
			//se o lugar apos a peca do oponente esta vago
			if (b.pieces[xo-2][yo-2]!=' ')
			{
				return FALSE;
			}
			else
			{
				return TRUE;
			}
		}
		else
		{
			return FALSE;
		}       
	}        
	
	return TRUE;	
}
